package com.example.springsecurity02.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;

/**
 * @ Description：自定义的资源权限规则配置类
 * 项目中需要有 这个的实例才不走security的默认配置类
 * @ Tool：IntelliJ IDEA
 * @ Author：lk
 * @ Date：2024-10-08-11:44 PM
 * @ Version：1.0
 */
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Override
    /**
     * 配置Spring Security的HTTP安全策略。
     * 本方法定义了哪些请求可以无需认证访问，哪些需要认证，以及登录表单的配置。
     * 特别注意，放行的资源（无需认证访问的资源）配置必须在需要认证的请求之前定义。
     */
    protected void configure(HttpSecurity http) throws Exception {
        // 开启资源认证功能
        http.authorizeHttpRequests()
                // 无需认证即可访问的登录页面
                .mvcMatchers("/login.html").permitAll()
                // 无需认证即可访问的首页
                .mvcMatchers("/index").permitAll()
                // 除了上述放行的资源外，所有请求必须经过认证才能访问
                .anyRequest().authenticated()
                .and()
                // 开启表单认证，配置登录页面和登录参数等信息
                .formLogin()
//                .loginPage("/doLogin") // 自定义登录页面的URL
                .usernameParameter("uname") // 登录表单中用户名的参数名称  修改默认的属性名
                .passwordParameter("passwd") // 登录表单中密码的参数名称   修改默认的属性名
                //.successForwardUrl("/index") // 用户认证成功后要转发的URL   认证成功 forward 跳转路径  始终在认证成功之后跳转到指定请求
//                .defaultSuccessUrl("/index", true) // 用户认证成功后默认要跳转的URL  认证成功 redirect 之后跳转  根据上一保存请求进行成功跳转
                .successHandler(new MyAuthenticationSuccessHandler()) // 设置自定义的认证成功处理器  前后分离项目自定义的登录页面  前后端分离处理方案

                // 认证失败后的处理
                //     下面两个属性前后端一体项目使用
//                .failureForwardUrl("/login.html") // 认证失败后要转发的URL  forward 跳转  数据放到request作用域
//                .failureUrl("/login.html") // 默认 认证失败后 redirect跳转  数据放到session作用域
                //      前后端分离项目 返回给前端失败信息  实现AutherticationFailureHandler接口即可
                .failureHandler(new MyAuthenticationFailureHandler())


                // 退出登录配置 默认的退出登录过滤器是默认加载的 直接GET访问logout即可完成退出
                // 我们用可以声明式的来实现更多的退出配置
                .and()
                .logout()
                //      退出默认是GET请求  如果想使用POST请求  需要自定义退出登录过滤器 可以同时匹配退出登录和退出登录的URL
                //            默认方式
//                .logoutUrl("/logout") // 退出登录的URL 可以自定义连接  默认是GET请求
                //            匹配多个URL
                .logoutRequestMatcher(new OrRequestMatcher(
                        new AntPathRequestMatcher("/logout", "GET"),
                        new AntPathRequestMatcher("/logout1", "POST")))
                .invalidateHttpSession(true) // 退出登录时是否使Session失效
                .clearAuthentication(true) // 退出登录时是否清除认证信息
                .logoutSuccessUrl("/index")  // 退出登录成功后要跳转的URL

                .and()
                // 禁用跨站请求伪造（CSRF）保护，通常在开发环境中使用，在生产环境中应重新启用
                .csrf().disable();
    }
}